package com.baymax.test.scene.view

import android.animation.ArgbEvaluator
import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.graphics.BlurMaskFilter
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorFilter
import android.graphics.MaskFilter
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.drawable.Drawable
import android.os.Build
import android.util.Log
import android.view.View
import android.view.View.LAYER_TYPE_SOFTWARE
import android.view.ViewGroup
import android.view.ViewOverlay
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.core.graphics.withSave
import com.baymax.test.scene.BaseScene
import com.baymax.test.scene.BuildConfig
import kotlin.properties.Delegates

/**
 * @title: 标题
 * @project: TestScene
 * @package: com.baymax.test.scene.view
 * @class: BulrDrawable
 * @description:
 *
 *
 * 类描述
 *
 * @version: 1.0
 * @createDate: 2023/5/5 14:15
 * @Copyright (C) 2023 YSTEN
 * @author: xuyujian
 */
class BlurDrawable : Drawable(), AnimatorUpdateListener {

    private val path = Path()
    private val rectF: RectF = RectF()

    //呼吸样式有两种
    //外呼吸灯 == 0、内呼吸灯 == 1
    //内呼吸灯只需要颜色渐变即可
    //外呼吸灯需要设置BlurMaskFilter
    var breathStyle: Int by Delegates.vetoable(0) { _, _, n ->
        shadowPaint.reset()
        when (n) {
            1 -> {
                shadowPaint.maskFilter = null
                shadowPaint.style = Paint.Style.FILL
            }

            0 -> {
//                val t = BlurMaskFilter.Blur.values().let {
//                    it.shuffle()
//                    it[0]
//                }
//                Log.w(TAG, "use effect %s", t)
                shadowPaint.maskFilter = shadowPaint.setMaskFilter(
                    BlurMaskFilter(
                        breathRadius,
                        BlurMaskFilter.Blur.OUTER
                    )
                )
            }

            else -> Unit
        }
        n == 1 || n == 0
    }


    /**
     * 呼吸灯半径。影响的呼吸灯范围
     * 只有外呼吸有效
     */
    var breathRadius: Float by Delegates.vetoable(40f) { _, _, n ->
        val valid = n > 0 && breathStyle == 0
        if (valid) {
            shadowPaint.reset()
            shadowPaint.setMaskFilter(BlurMaskFilter(n, BlurMaskFilter.Blur.OUTER))
        } else {
//            KLog.w("BreathDrawable", "configOuterBreath fail %s ,type =%s", n, breathStyle)
        }
        valid
    }

    /**
     * 绘制呼吸框内容的圆角,此区域需要与内容显示区域重合。
     * 设置path时不能设置MAX,否则4.4不生效
     * 需要改为高度的一半
     */
   var corner: Float by Delegates.vetoable(0f) { _, o, n ->
        val change = n >= 0f && o != n
        createBreathPath(n, rectF)
        change
    }

    var offsetDx = 0f
        private set
    var offsetDy = 0f
        private set

    private val shadowPaint = Paint().apply {
//        setColor(Color.WHITE)
        if (breathStyle == 0) {
            maskFilter = BlurMaskFilter(breathRadius, BlurMaskFilter.Blur.OUTER)
        } else {
            style = Paint.Style.FILL
            maskFilter = null
        }
    }


    var animationDuration: Long by Delegates.vetoable(1500L) { _, _, n ->
        if (n > 0) {
            animator?.setDuration(n)
        }
        n > 0
    }
    var animator: ValueAnimator? = null
    private var cachedLayerType: Int = View.LAYER_TYPE_NONE
    var colors: IntArray = intArrayOf(Color.BLUE, Color.YELLOW)
        set(value) {
            field = value
            animator?.setIntValues(*value)
        }

    fun start() {
        initStart()
        if (animator == null) {
            val animator = ValueAnimator.ofInt(*colors)
            animator.setEvaluator(ArgbEvaluator())
            animator.interpolator = AccelerateDecelerateInterpolator()
            animator.repeatCount = ValueAnimator.INFINITE
            animator.repeatMode = ValueAnimator.REVERSE
            animator.duration = animationDuration
            animator.addUpdateListener(this)
            this.animator = animator
            animator.start()
        }
        animator?.start()
    }

    fun stop() {
        initStop()
        animator?.cancel()
    }


    override fun onBoundsChange(bounds: Rect) {
        super.onBoundsChange(bounds)
        path.reset()
        //现在框view自身包含了外部blur阴影的范围，计算绘制区域时需要扣除radius
        rectF.set(bounds)
        rectF.offset(offsetDx, offsetDy)
        //path.addRoundRect(rectF, new float[]{corner, corner, corner, corner, corner, corner, corner, corner}, Path.Direction.CW)
        //设置圆角为高度的一般
        //如果需要单独修改设置corner即可
        corner =  bounds.height() / 2f
    }

    private fun createBreathPath(corner: Float, bounds: RectF) {
        println("createBreathPath $corner , $bounds")
        val c = corner
        path.reset()
        path.addRoundRect(
            bounds,
            floatArrayOf(c, c, c, c, c, c, c, c),
            Path.Direction.CW
        )
    }

    private fun initStart() {
        findCallBackAsView()?.apply {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && this is ViewOverlay) {
//                this.background = null
            } else {
                val parent = this.parent
                if (parent is ViewGroup) {
                    parent.clipChildren = false
                    parent.clipToPadding = false
                    initParentLayer(parent)
                }
            }

        }
    }


    private fun initStop() {
        findCallBackAsView()?.apply {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && this is ViewOverlay) {
//                this.background = null
            } else {
                val parent = this.parent
                if (parent is ViewGroup) {
                    resetParentLayer(parent)
                }
            }
        }
    }

    private fun findCallBackAsView(): View? {
        var hostCallback = this.callback
        while (hostCallback is Drawable) {
            hostCallback = hostCallback.callback
        }
//        KLog.d("BreathDrawable", "find Call back view %s ,%s", this.callback, hostCallback)
        return hostCallback as? View
    }

    private fun initParentLayer(parent: ViewGroup) {
        cachedLayerType = parent.layerType
        if (cachedLayerType != LAYER_TYPE_SOFTWARE) {
            parent.setLayerType(LAYER_TYPE_SOFTWARE, null);
        }
    }

    private fun resetParentLayer(parent: ViewGroup) {
        parent.setLayerType(cachedLayerType, null)
    }

    private val p = Paint().apply {
        color = Color.RED
        style = Paint.Style.FILL
        textSize = 14f
    }

    override fun draw(canvas: Canvas) {
        canvas.save()
//        canvas.drawColor(Color.TRANSPARENT  )
//        path.addRoundRect(
//            rectF,
//            floatArrayOf(corner, corner, corner, corner, corner, corner, corner, corner),
//            Path.Direction.CW
//        )
        canvas.drawPath(path, shadowPaint)
        //todo
        if (BuildConfig.DEBUG) {
            canvas.drawCircle(0f, 0f, 4f, p)
            canvas.drawCircle(0f, bounds.height().toFloat(), 4f, p)
            canvas.drawText(breathStyle.toString(), 16f , 16f ,p)
        }
        canvas.restore()
    }

    override fun setAlpha(alpha: Int) {
        shadowPaint.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {

    }

    override fun getOpacity(): Int = shadowPaint.alpha
    override fun onAnimationUpdate(animation: ValueAnimator) {
        shadowPaint.color = animation.animatedValue as Int
        invalidateSelf()
    }


    fun setOffset(dx: Float, dy: Float) {
        this.offsetDx = dx
        this.offsetDy = dy
        rectF.set(bounds)
        rectF.offset(dx, dy)
        createBreathPath(corner, rectF)
    }
}